// mmAtoD.c

/*********************************************************************
/*File: mmAtoD.c
/*Date: June 18, 2010
/*Descriptioin: Contains functions for initializing and reading data
/*				from the A to D converter, which is connected to the 
/*				Mentor pressure transducer.
/*Author: Jason Reber
/*********************************************************************/
#include "pic.h"


/*****************************************************************************/
/*	FUNCTION PROTOTYPES
/*****************************************************************************/
void mmInitAtoD();
INT16 mmGetAtoD();
INT16 mmFilterAtoD(void);

/*****************************************************************************/
/* LOCAL VARIABLES
/*****************************************************************************/

/****************************************************************************
  Function:
    void mmInitAtoD(void)

  Summary:
    Initializes the A to D converter on the PIC16F1938 to read the output from
    the Mentor pressure transducer.

  Precondition:
    None

  Parameters:
    None

  Returns:
    None

  Remarks:
    
  ***************************************************************************/
void mmInitAtoD(void)
{
    TRISA0 = 1;		//configure A0 as an input (pin 5 on device)
    ANSA0 = 1;		//configure A0 as an analog input (necessary for A to D)
}

/****************************************************************************
  Function:
    INT16 mmGetAtoD(UINT8 channel)

  Summary:
    Initializes the inputs on the F1 Evaluation platform

  Description:
    This function performs a single ADC conversion blocking until it is finished.
    The result is returned as a signed 16-bit integer.
    This function blocks until the ADC is finished.
 
  Precondition:
    None

  Parameters:
    UINT8 channel : the channel number to convert

  Returns:
    INT16 of the current ADC value

  Remarks:
    The ADC is turned on and off in this function.
    The channel is left at the last converted channel.
    This function waits 4 instruction cycles (16 Tosc) for acquisition.
  ***************************************************************************/
INT16 mmGetAtoD()
{
	char x;
    //ADON = 1;                       // ADC is ON
    ADCON1 |= 0x10;					//Select FOSC/8 conversion clock rate
    ADNREF = 0;                     // Negative Reference = VSS
    ADPREF0 = 1;                    
    ADPREF1 = 1;					// Positive Reference = FVR
    ADPREF1 = 0;					//Positive Reference = FVR
    ADFM = 1;                       // right justify
    ADCON0bits.CHS = 0;       		// set ADC channel to 0 (AN0)
    NOP();                          // wait a little for acquisition.
    NOP();
    NOP();
    NOP();
    GO_nDONE = 1;                   // Start the conversion
    // wait for conversion
    for(x=200;x;x--)                // avoid getting stuck
      if(GO_nDONE == 0) break;      // exit as soon as results are ready

    //ADON = 0;                       // turn ADC off to save a little power
    return (ADRESH << 8 | ADRESL);  // return the result
}

/****************************************************************************
  Function:
    INT16 mmFilterAtoD(void)

  Summary:
    Measures the potentiometer and returns a filtered result.

  Description:
    This function uses get_adc(8) to measure channel 8.  Then it performs a
    rolling average filter and returns the result.
 
  Precondition:
    None

  Parameters:
    None

  Returns:
    INT16 filtered measurement of the potentiometer.

  Remarks:
    The rolling average filter is adequate for simple DC measurments.
  ***************************************************************************/

INT16 mmFilterAtoD(void)

// 32 point rolling average filter with simulated infinite sum
{
    INT16  integrator = 0;
    INT16  modval = 0;
    //INT16         average;
    unsigned char i;
    ADON = 1;   //turn on A to D converter
    integrator = mmGetAtoD();   //do a quick read and throw away the result.
    integrator = 0;
    for(i=0;i<16;i++)
       integrator += mmGetAtoD();
    modval = (integrator & 0x0f);  //preserve low nibble only
    integrator &= 0xfff0;		//preserve upper 3 nibbles
    integrator >>=4; 		//shift right 4 bits. 
    if(modval > 8)
      integrator += 1;
    ADON = 0;
    return(integrator);
    
    /*modval = integrator;
    modval %= 16;
    integrator /= 16;
    if(modval>=8)
      integrator+=1;
    ADON = 0;
    return(integrator);  
    //integrator += mmGetAtoD();
    //average = integrator / 32;
    //integrator -= average;
    //return (average+1);   */
}